const fs = require('fs');
const path = require('path');
const logger = require('./logger');

class MinArgs {
  constructor() {
    // 单例模式实现
    if (MinArgs.instance) {
      return MinArgs.instance;
    }
    MinArgs.instance = this;

    // 初始化 env 和 argv 对象
    this.env = {};
    this.argv = {
      _: [], // 位置参数
      verbose: 0, // 日志等级
      help: false, // 是否请求帮助
    };

    // 加载.env文件到 env
    this.loadEnvFile();

    // 合并环境变量到 env
    this.mergeProcessEnv();

    // 处理命令行参数并合并到 argv
    this.parseArguments(process.argv.slice(2));

    // 合并 argv 到 env，argv 覆盖 env
    this.mergeEnvToArgv();

    // 设置环境变量和日志级别
    this.setEnvironmentVariables();
    this.setLogLevel();
  }

  setEnvironmentVariables() {
    if (this.argv.force) {
      process.env.FORCE_UPDATE = 'true';
    }
    if (this.argv.job) {
      process.env.script_JOB = this.argv.job;
    }
  }

  setLogLevel() {
    switch (this.argv.verbose) {
      case 1:
        logger.setLevel('warn');
        break;
      case 2:
        logger.setLevel('info');
        break;
      case 3:
        logger.setLevel('debug');
        break;
      default:
        logger.setLevel('error');
    }
  }

  showHelp(type) {
    switch (type) {
      case 'analysis':
        console.log(
          `
🚀 项目命令行参数说明

用法：
  analysis.exe [选项]

可用选项：

  -h, --help            显示此帮助信息

  -f, --force           强制执行，不检查任务是否已完成

  -v                    显示 warn 及以上日志
  -vv                   显示 info 及以上日志
  -vvv                  显示 debug 及所有日志

  -t, --type=gw,qy      指定要执行的任务类型 (默认: gw,qy)
                        支持多个: --type=gw,qy
  --job=JobA            指定要执行的任务 (默认: JobA)
                        支持多个: --job=JobA,JobB

示例：
  analysis.exe --job=JobA -vv
  analysis.exe --job=JobA,JobB
  analysis.exe --help

💡 提示：不带任何参数时，默认执行 JobA，只显示 error 日志。
`.trim()
        );
        break;
      case 'main':
        console.log(
          `
🚀 项目命令行参数说明

用法：
  main.exe [选项]

可用选项：

  -h, --help            显示此帮助信息

  -f, --force           强制执行，不检查任务是否已完成

  -v                    显示 warn 及以上日志
  -vv                   显示 info 及以上日志
  -vvv                  显示 debug 及所有日志

  --job=JobA            指定要执行的任务 (默认: JobA)
                        支持多个: --job=JobA,JobB

  --headless=false      设置无头模式 (默认: true)
  --no-headless         等同于 --headless=false
  --qy                  指定要执行的任务类型 (指定获取的企业名称: 仅JobB支持)
                        支持多个: --qy=企业1,企业2
  --check               详情检查模式（确认岗位是否依然有效：仅JobA支持）
  --unlogin             跳过登录流程（仅JobB支持）

  --executable-path=... 指定浏览器可执行文件路径
                        例如: --executable-path="C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"

示例：
  main.exe --job=JobA -vv
  main.exe --job=JobA,JobB --no-headless
  main.exe --help

💡 提示：不带任何参数时，默认执行 JobA，无头模式，只显示 error 日志。
`.trim()
        );
        break;
    }
  }

  resolveEnvPath() {
    if (process.pkg || process.env.NODE_NEXE) {
      const exeDir = path.dirname(process.execPath); // .exe 所在目录
      this.env['ProjectRoot'] = exeDir;
      return path.join(exeDir, '.env');
    }

    let cwdEnv = path.join(process.cwd(), '.env');
    if (fs.existsSync(cwdEnv)) {
      this.env['ProjectRoot'] = process.cwd();
      return cwdEnv;
    }

    const projectRoot = path.resolve(__dirname, '..', '..');
    this.env['ProjectRoot'] = projectRoot;
    return path.join(projectRoot, '.env');
  }

  loadEnvFile() {
    const envPath = this.resolveEnvPath();

    try {
      if (fs.existsSync(envPath)) {
        const envContent = fs.readFileSync(envPath, 'utf8');
        this.parseEnvContent(envContent);
        console.log(`[环境变量] 已成功加载.env文件: ${envPath}`);
      } else {
        logger.error(`[环境变量] 未找到.env文件: ${envPath}`);
      }
    } catch (error) {
      logger.error('[错误] 加载.env文件失败:', error);
    }
  }

  parseEnvContent(content) {
    let currentSection = null;

    content.split('\n').forEach(line => {
      if (!line || line.startsWith('#')) return;

      if (line.startsWith('[')) {
        currentSection = line.replace(/[\[\]\r]/g, '');
        return;
      }

      const [key, value] = line.split('=', 2);
      if (key && value) {
        const cleanKey = key.trim();
        const cleanValue = value.trim().replace(/^"|"$/g, '');

        // 存储到对应的section
        if (currentSection) {
          if (!this.env[currentSection]) {
            this.env[currentSection] = {};
          }
          this.env[currentSection][cleanKey] = cleanValue;
        } else {
          // 全局变量
          this.env[cleanKey] = cleanValue;
        }
      }
    });
  }

  mergeProcessEnv() {
    Object.keys(process.env).forEach(key => {
      if (!this.env[key]) {
        this.env[key] = process.env[key];
      }
    });

    Object.keys(process.env).forEach(key => {
      const parts = key.split('_');
      if (parts.length >= 2) {
        const section = parts[0];
        const sectionKey = parts.slice(1).join('_');

        if (!this.env[section] || typeof this.env[section] !== 'object') {
          this.env[section] = {};
        }

        if (!this.env[section][sectionKey]) {
          this.env[section][sectionKey] = process.env[key];
        }
      }
    });
  }

  parseArguments(args) {
    let i = 0;
    while (i < args.length) {
      const arg = args[i];

      // 处理 -h, --help
      if (arg === '-h' || arg === '--help') {
        this.argv.help = true;
        i++;
        continue;
      }

      // 处理 -f, --force
      if (arg === '-f' || arg === '--force') {
        this.argv.force = true;
        i++;
        continue;
      }

      // 处理 -t, --type=gw,qy
      if (arg.startsWith('-t=')) {
        this.argv.type = arg.substring(3);
        i++;
        continue;
      }
      if (arg === '-t' || arg === '--type') {
        // 如果参数和值是分开的，比如 `-t gw,qy` 或 `--type gw,qy`
        this.argv.type = args[i + 1];
        i += 2;
        continue;
      }

      // 处理 -v, -vv, -vvv
      if (arg === '-v') {
        this.argv.verbose = 1;
      } else if (arg === '-vv') {
        this.argv.verbose = 2;
      } else if (arg === '-vvv') {
        this.argv.verbose = 3;
      }

      // 处理 --headless=true/false
      else if (arg.startsWith('--headless=')) {
        const value = arg.split('=')[1].trim().toLowerCase();
        this.argv.headless = value === 'true' || value === '1' || value === '';
      }
      // 处理 --no-headless
      else if (arg === '--no-headless') {
        this.argv.headless = false;
      }

      // 处理 --job=xxx
      else if (arg.startsWith('--job=')) {
        this.argv.job = arg.split('=')[1];
      }
      // 添加--qy参数解析
      else if (arg.startsWith('--qy=')) {
        this.argv.qy = arg.split('=')[1];
      }
      // 处理 --executable-path=...
      else if (arg.startsWith('--executable-path=')) {
        this.argv.executablePath = arg.split('=')[1];
      }

      // 其他 --key=value
      else if (arg.startsWith('--')) {
        const [key, value] = arg.slice(2).split('=', 2);
        this.argv[key] = value === undefined ? true : value;
      }

      // 位置参数（如 main.exe JobA）
      else {
        this.argv._.push(arg);
      }

      i++;
    }
  }

  mergeEnvToArgv() {
    // 遍历 env 对象，如果存在 argv[key] 则赋值 env[key] = argv[key]
    Object.keys(this.env).forEach(key => {
      // 如果 argv[key] 存在，则用 argv[key] 覆盖 env[key]
      if (this.argv[key] !== undefined) {
        this.env[key] = this.argv[key];
      }
    });
    if (this.argv.executablePath !== undefined) {
      this.env.CHROME_PATH = this.argv.executablePath;
    }
  }
}

// 初始化参数
const minArgsInstance = new MinArgs();

module.exports = {
  MinArgs,
  showHelp: minArgsInstance.showHelp.bind(minArgsInstance),
  env: minArgsInstance.env,
  argv: minArgsInstance.argv,
};
